/*
 * Copyright (C) 2025 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package top.xbaistack.ws;

import org.apache.commons.collections.CollectionUtils;
import top.xbaistack.common.WebSocketResponse;
import top.xbaistack.exception.BaseException;
import top.xbaistack.game.Player;
import top.xbaistack.game.Room;
import top.xbaistack.utils.WebSocket;

import javax.websocket.Session;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 房间管理器，用于统一管理房间的一些行为。
 *
 * @author xbaistack
 * @since 2025/03/25
 */
public final class RoomManager {
    private static final ConcurrentHashMap<String, Room> rooms = new ConcurrentHashMap<>(128);

    public static Room newRoom(int rows, int cols) {
        Room room = Room.create(rows, cols);
        rooms.put(room.getId(), room);
        return room;
    }

    public static Room getRoom(String roomId) {
        return getRoom(roomId, true);
    }

    public static Room getRoom(String roomId, boolean check) {
        Room room = rooms.get(roomId);
        if (room == null && check) {
            throw new BaseException("房间不存在或已解散！");
        }
        return room;
    }

    public static void join(Session session, String roomId, String playerId) {
        Room room = getRoom(roomId);
        Player player = room.getPlayer(playerId);
        room.join(playerId, session);
        room.setFrozen(room.isOver() ? true : player.isFrozen());
        room.setResult(player.isWinner() ? "我赢啦~" : "我输了！");
        WebSocket.sendMessage(session, WebSocketResponse.init(room));
        List<Player> otherPlayers = room.getOtherPlayers(playerId);
        if (CollectionUtils.isNotEmpty(otherPlayers)) {
            otherPlayers.forEach(p -> p.sendMessage(WebSocketResponse.online()));
        }
    }

    public static void offline(String roomId, String playerId) {
        Room room = getRoom(roomId, false);
        if (room != null) {
            if (room.offline(playerId)) {
                rooms.remove(roomId);
            } else {
                List<Player> onlines = room.getOnlinePlayers();
                if (CollectionUtils.isNotEmpty(onlines)) {
                    onlines.forEach(player -> player.sendMessage(WebSocketResponse.offline()));
                }
            }
        }
    }

    public static void exit(String roomId) {
        Room room = getRoom(roomId, false);
        if (room != null) {
            List<Player> players = room.getOnlinePlayers();
            for (Player player : players) {
                player.sendMessage(new WebSocketResponse("exit", "退出游戏！"));
                player.exit();
            }
            rooms.remove(roomId);
        }
    }

}
